import React, { LegacyRef, useCallback, useState } from 'react';
import { Button, Checkbox, Form, Input, Toast } from 'antd-mobile';
import { EyeInvisibleOutline, EyeOutline } from 'antd-mobile-icons';
import NavBar from '@/components/NavBar/NavBar';
import LoginHeader from '@/views/Login/components/LoginHeader/LoginHeader';
import LoginFooter from '@/views/Login/components/LoginFooter/LoginFooter';
import useCountdown from '@/hooks/useCountdown';
import { useEnhanceDispatch } from '@/hooks';
import { Link, useNavigate } from 'react-router-dom';
import { codeLogin, passwordLogin, sendCodeThunk } from '@/store/modules/loginStore';
import type { CodeLoginParams, PasswordLoginParams } from '@/type/LoginType';
import type { FormInstance } from 'antd-mobile/es/components/form';
import { rules } from '@/utils/rules';
import './Login.scss';


export type LoginType = 'passwordLogin' | 'codeLogin'

export type PasswordType = 'password' | 'text'

const Login: React.FunctionComponent = () => {
  const navigate = useNavigate();
  const enhanceDispatch = useEnhanceDispatch();
  // 自定义的倒计时hooks
  const { timeId, countdown, start, setStart, subCountdown, setCountdown } = useCountdown(60);
  // 表单组件实例
  const [formInstance] = Form.useForm<LegacyRef<FormInstance> | undefined>();
  // 左边插槽内容
  const left = useCallback(() => (<span>返回</span>), []);
  // 中间插槽内容
  const children = useCallback(() => (<span>优医问诊 登录</span>), []);
  // 右边插槽内容
  const right = useCallback(() => (<Link to="/register">注册</Link>), []);
  // 登录方式
  const [loginType, setLoginType] = useState<LoginType>('passwordLogin');
  // 密码框的类型
  const [passwordType, setPasswordType] = useState<PasswordType>('password');
  //是否勾选用户协议
  const [isAgree, setIsAgree] = useState<boolean>(true);
  // 登录的loading效果
  const [loading, setLoading] = useState<boolean>(false);


  /**
   * @description 密码登录的回调函数
   * */
  const handlePasswordLogin = async (passwordLoginParams: PasswordLoginParams) => {
    try {
      await enhanceDispatch(passwordLogin(passwordLoginParams)).unwrap();
      navigate('/');
    } catch (rejectedValueOrSerializedError: any) {
      Toast.show(rejectedValueOrSerializedError);
    }
  };

  /**
   * @description 验证码登录的回调函数
   * */
  const handleCodeLogin = async (codedLoginParams: CodeLoginParams) => {
    try {
      await enhanceDispatch(codeLogin(codedLoginParams)).unwrap();
      navigate('/');
    } catch (rejectedValueOrSerializedError: any) {
      Toast.show(rejectedValueOrSerializedError);
    }
  };

  /**
   * 获取验证码的回调函数
   * */
  const handleSendCode = async () => {
    try {
      await enhanceDispatch(sendCodeThunk({ mobile: formInstance.getFieldValue('mobile'), type: 'login' })).unwrap();
    } catch (rejectedValueOrSerializedError: any) {
      Toast.show(rejectedValueOrSerializedError);
    }
  };

  /**
   * @description LoginHeader子组件调用的回调函数用于切换登录方式
   * */
  const changeLoginType = useCallback((loginType: LoginType) => {
    if (loginType === 'passwordLogin') {
      setStart(false);
      setCountdown(60);
    }
    setLoginType(loginType);
  }, [loginType]);

  /**
   * @description 切换密码框类型的回调函数
   * */
  const changePasswordType = useCallback(() => {
    setPasswordType(passwordType === 'password' ? 'text' : 'password');
  }, [passwordType]);

  /**
   * @description 点击发送验证码按钮的回调函数
   * */
  const sendCode = () => {
    formInstance.validateFields(['mobile']).then(async result => {
      await handleSendCode();
      subCountdown();
    }).catch(error => {
      const message = error.errorFields[0].errors[0];
      Toast.show(message);
    });
  };

  /**
   * @description 提交表单且数据验证成功后触发的回调函数
   * */
  const handleFinsh = async (values: PasswordLoginParams & CodeLoginParams) => {
    try {
      if (!isAgree) return Toast.show('请勾选用户协议');
      setLoading(true);
      if (loginType === 'passwordLogin') {
        await handlePasswordLogin(values);
      } else {
        await handleCodeLogin(values);
      }
      Toast.show({ icon: 'success', content: `${loginType === 'passwordLogin' ? '密码登录成功' : '验证码登录成功'}` });
    } catch (error: any) {

    } finally {
      setLoading(false);
    }
  };

  /**
   * @description 提交表单且数据验证失败后触发的回调函数
   * */
  const handleFinishFailed = (error: any) => {
    const message = error.errorFields[0].errors[0];
    Toast.show(message);
  };

  /**
   * @description 根据passwordType按需渲染文本框类型
   * */
  const renderPasswordType = useCallback(() => passwordType === 'password' ? <EyeInvisibleOutline fontSize={20} /> : <EyeOutline fontSize={20} />, [passwordType]);

  /**
   * @description 根据loginType按需渲染登录方式
   * */
  const renderLoginType = useCallback(() => {
    if (loginType === 'passwordLogin') {
      return (
        <Form.Item name="password" rules={rules.password} extra={<span onClick={changePasswordType}>{renderPasswordType()}</span>}>
          <Input type={passwordType} placeholder="请输入密码" />
        </Form.Item>
      );
    } else {
      return (
        <Form.Item name="code" rules={rules.code} extra={<a onClick={sendCode}>{start ? `${countdown}秒后重新获取` : '发送验证码'}</a>}>
          <Input type={passwordType} placeholder="请输入短信验证码" />
        </Form.Item>
      );
    }
  }, [loginType, countdown, passwordType]);

  return (
    <div className="login">
      {/*导航栏组件*/}
      <NavBar back={left()} right={right()}></NavBar>
      {/*登录头部组件*/}
      <LoginHeader loginType={loginType} changeLoginType={changeLoginType}></LoginHeader>
      {/*登录表单*/}
      <Form mode="card" form={formInstance} hasFeedback={false} onFinish={handleFinsh} onFinishFailed={handleFinishFailed}>
        <Form.Item name="mobile" rules={rules.mobile}>
          <Input placeholder="请输入手机号" />
        </Form.Item>
        {/*按需渲染密码框和验证码文本框*/}
        {renderLoginType()}
        <Form.Item className="last">
          <Checkbox checked={isAgree} onChange={(checked) => setIsAgree(checked)}><span>我已同意</span><a>用户协议</a><span>及</span><a>隐私条款</a></Checkbox>
        </Form.Item>
        <Form.Item className="last">
          <Button loading={loading} color="primary" type="submit">登录</Button>
        </Form.Item>
      </Form>
      {/*底部*/}
      <LoginFooter></LoginFooter>
    </div>
  );
};

export default Login;